package com.py.credit.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.py.credit.dao.ModelBaseDao;
import com.py.credit.dao.ScoreRunningDao;
import com.py.credit.entity.ModelChoose;
import com.py.credit.entity.ModelDetail;
import com.py.credit.entity.ScoreRunningPc;
import com.py.credit.service.XypjRemoteBaseService;
import com.py.credit.service.ScoreRunningService;
import com.py.credit.utils.SQLBuilder;
import com.py.framework.core.common.Page;

@Service
public class ScoreRunningServiceImpl implements ScoreRunningService {

	@Autowired
	private ScoreRunningDao scoreRunningDao;

	@Autowired
	private ModelBaseDao modelBaseDao;

	@Autowired
	private XypjRemoteBaseService xypjRemoteBaseService;

	@Override
	public List<Map<String, Object>> getByConditionForPage(List<String> columns, String[] additionalColumns,
			String conditionStr, Page page, String mainType) {
		List<String> conditions = SQLBuilder.createConditionSql(conditionStr);
		List<Map<String, Object>> batchLogs = scoreRunningDao.selectByConditionForPage(columns, additionalColumns,
				conditions, page, mainType);

		return batchLogs;
	}

	@Override
	public List<ModelDetail> selectPcDetailByConditionForPage(List<String> columns, String[] additionalColumns,
			String conditionStr, Page page, String pcId) {
		List<String> conditions = SQLBuilder.createConditionSql(conditionStr);
		List<ModelDetail> batchLogs = scoreRunningDao.selectPcDetailByConditionForPage(columns, additionalColumns,
				conditions, page, pcId);

		return batchLogs;
	}

	@Override
	public List<ModelChoose> getModelListByMainTypeForPage(List<String> columns, String[] additionalColumns,
			String conditionStr, Page page, String mainType) {
		List<String> conditions = SQLBuilder.createConditionSql(conditionStr);
		List<ModelChoose> batchLogs = scoreRunningDao.getModelListByMainTypeForPage(columns, additionalColumns,
				conditions, page, mainType);

		return batchLogs;
	}

	@Override
	public void addSch(String modelId, String initIndexScore, String mainType, String executionType, String frenquency,
			String day, String time, String nextTime) {
		scoreRunningDao.delSchByMainType(mainType);
		scoreRunningDao.addSch(modelId, initIndexScore, mainType, executionType, frenquency, day, time, nextTime);
	}

	@Override
	public void updatePcCallablility(String id, String isCallable) {
		scoreRunningDao.updatePcCallablility(id, isCallable);

	}

	@Transactional
	@Override
	public void autoScore(ScoreRunningPc scoreRunningPc, String list) {
		long start = System.currentTimeMillis();
		Map<String, String> m = scoreRunningDao.selectSchInfoByMainType(scoreRunningPc.getMainType());
		scoreRunningPc.setInitIndexScore(Double.parseDouble(m.get("initIndexScore")));
		scoreRunningPc.setModelId(m.get("modelId"));
		scoreRunningPc.setExecutionType(m.get("executionType"));
		scoreRunningDao.addPc(scoreRunningPc);
		List<String> l = Arrays.asList(list.split(","));
		scoreRunningDao.initPcDetailByEvalInfo(scoreRunningPc.getId(), scoreRunningPc.getModelId(), l);
		double weightAll = 0;
		List<Map<String, String>> listZz = scoreRunningDao.selectZzIndexesByModel(scoreRunningPc.getModelId());
		for (int i = 0; i < listZz.size(); i++) {
			String indexCatModelId = listZz.get(i).get("indexCatModelId");
			String inputType = listZz.get(i).get("inputType");
			double weightIndex = Double.parseDouble(listZz.get(i).get("weight"));
			String pId = listZz.get(i).get("pId");
			weightIndex = weightIndex / 100;
			weightIndex = new BigDecimal(weightIndex).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
			double weight = getWeight(weightIndex, scoreRunningPc.getModelId(), pId, "category");
			weightAll += weight;
			String type = listZz.get(i).get("type");
			List<Map> rulesSfyzz = modelBaseDao.getRuleListByIndexModelCatForZz(listZz.get(i).get("indexCatModelId"),
					"SFYZZ");
			List<Map> rulesZzsfdq = modelBaseDao.getRuleListByIndexModelCatForZz(listZz.get(i).get("indexCatModelId"),
					"ZZSFDQ");
			double rate = 1;
			if (rulesSfyzz != null && rulesSfyzz.size() > 0 && rulesZzsfdq != null && rulesZzsfdq.size() > 0) {
				rate = 0.5;
			}
			double scoreTrue = 0;
			double scoreFalse = 0;
			if (rulesSfyzz != null && rulesSfyzz.size() > 0) {
				for (int j = 0; j < rulesSfyzz.size(); j++) {
					if (rulesSfyzz.get(j).get("start").equals("1")) {
						scoreTrue = Double.parseDouble(String.valueOf(rulesSfyzz.get(j).get("score")));
						continue;
					}
					if (rulesSfyzz.get(j).get("start").equals("2")) {
						scoreFalse = Double.parseDouble(String.valueOf(rulesSfyzz.get(j).get("score")));
						continue;
					}
				}
			}

			Map<String, Object> cardsMap = new HashMap<>();
			cardsMap.put("type", inputType);
			cardsMap.put("rate", rate);
			cardsMap.put("pcId", scoreRunningPc.getId());
			cardsMap.put("indexCatModelId", indexCatModelId);
			cardsMap.put("weight", weight);
			List<String> listSelected = new ArrayList<String>();
			if (!StringUtils.isBlank(list)) {
				listSelected = Arrays.asList(list.split(","));
			}
			cardsMap.put("listSelected", listSelected);

			cardsMap.put("scoreTrue", scoreTrue);
			cardsMap.put("scoreFalse", scoreFalse);
			scoreRunningDao.insertCardsSfyzzAll(cardsMap);
			if (rulesZzsfdq != null && rulesZzsfdq.size() > 0) {
				for (int j = 0; j < rulesZzsfdq.size(); j++) {
					if (rulesZzsfdq.get(j).get("start").equals("1")) {
						scoreTrue = Double.parseDouble(String.valueOf(rulesZzsfdq.get(j).get("score")));
						continue;
					}
					if (rulesZzsfdq.get(j).get("start").equals("2")) {
						scoreFalse = Double.parseDouble(String.valueOf(rulesZzsfdq.get(j).get("score")));
						continue;
					}
				}
			}

			scoreRunningDao.insertCardsZzsfdqAll(cardsMap);
		}
		List<Map<String, String>> listSql = scoreRunningDao.selectSqlIndexesByModel(scoreRunningPc.getModelId());
		for (int i = 0; i < listSql.size(); i++) {
			String sql = listSql.get(i).get("callContent");
			String indexCatModelId = listSql.get(i).get("indexCatModelId");
			String inputType = listSql.get(i).get("inputType");
			double weightIndex = Double.parseDouble(listSql.get(i).get("weight"));
			weightIndex = weightIndex / 100;
			String pId = listSql.get(i).get("pId");
			double weight = getWeight(weightIndex, scoreRunningPc.getModelId(), pId, "category");
			weightAll += weight;
			List<Map> listV = xypjRemoteBaseService.autoScoreByIndexSql(scoreRunningPc.getMainType(), sql, list, "");
			if (listV != null && listV.size() > 0) {
				scoreRunningDao.initIndexInfo(scoreRunningPc.getId(), indexCatModelId, listV);
			}
			if (StringUtils.isNotBlank(inputType) && "2".equals(inputType)) {
				scoreRunningDao.updateIndexScoreForDict(scoreRunningPc.getId(), indexCatModelId, weight);
			} else {
				scoreRunningDao.updateIndexScore(scoreRunningPc.getId(), indexCatModelId, weight);
			}
		}

		// 财务指标
		List<Map<String, String>> listFinance = scoreRunningDao
				.selectFinanceIndexesByModel(scoreRunningPc.getModelId());
		for (int i = 0; i < listFinance.size(); i++) {
			String field = listSql.get(i).get("treeElem");
			String indexCatModelId = listSql.get(i).get("indexCatModelId");
			String inputType = listSql.get(i).get("inputType");
			double weightIndex = Double.parseDouble(listSql.get(i).get("weight"));
			String pId = listSql.get(i).get("pId");
			weightIndex = weightIndex / 100;
			weightIndex = new BigDecimal(weightIndex).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
			double weight = getWeight(weightIndex, scoreRunningPc.getModelId(), pId, "category");
			weightAll += weight;
			scoreRunningDao.insertFinance(field, l);
			if (StringUtils.isNotBlank(inputType) && "2".equals(inputType)) {
				scoreRunningDao.updateIndexScoreForDict(scoreRunningPc.getId(), indexCatModelId, weight);
			} else {
				scoreRunningDao.updateIndexScore(scoreRunningPc.getId(), indexCatModelId, weight);
			}

		}
		double leftWeight = 1 - weightAll;
		List<Map> listAll = xypjRemoteBaseService.getAllEnterprise(scoreRunningPc.getMainType(), list, "");
		scoreRunningDao.initPcDetailByModelTest(scoreRunningPc.getId(), listAll);
		scoreRunningDao.deleForUserReport(scoreRunningPc.getId());
		scoreRunningDao.updatePcDetailForScore(scoreRunningPc.getId(), scoreRunningPc.getInitIndexScore(), leftWeight);
		scoreRunningDao.updateBgbhByPc(scoreRunningPc.getId());
		scoreRunningDao.updatePcDetailRank(scoreRunningPc.getId(), scoreRunningPc.getModelId());
		long end = System.currentTimeMillis();
		scoreRunningDao.updatePcExecuteTime(String.valueOf(end - start), scoreRunningPc.getId());

	}

	@Override
	public void addPc(ScoreRunningPc scoreRunningPc) {
		scoreRunningDao.addPc(scoreRunningPc);

	}

	public double getWeight(double weight, String modelId, String indexCatModelId, String type) {
		Map<String, String> m = scoreRunningDao.getParentWeight(modelId, indexCatModelId, type);
		weight = Double.parseDouble(m.get("weight")) * weight / 100;
		type = "category";
		if (String.valueOf(m.get("pId")).equals("0") || String.valueOf(m.get("pId")).equals("")) {
			return weight;
		} else {
			return getWeight(weight, modelId, String.valueOf(m.get("pId")), type);
		}
	}

	@Override
	public List<Map<String, String>> selectModel(String zone, String industry, String reportType, String mainType) {
		return scoreRunningDao.selectModel(zone, industry, reportType, mainType);
	}

	@Override
	public Map<String, String> selectSchInfoByMainType(String mainType) {
		return scoreRunningDao.selectSchInfoByMainType(mainType);
	}

	@Override
	public void updateSchStatus(String status, String mainType) {
		scoreRunningDao.updateSchStatus(status, mainType);

	}

	@Override
	public Map<String, String> selectScoreInfoByTybm(String modelId, String tybm) {
		return scoreRunningDao.selectScoreInfoByTybm(modelId, tybm);
	}

	@Override
	public Map<String, String> selectScoreInfoByTybmAndPcid(String pcId, String tybm) {
		return scoreRunningDao.selectScoreInfoByTybmAndPcid(pcId, tybm);
	}

	@Override
	public List<String> getAllTybms() {
		return scoreRunningDao.getAllTybms();
	}

	@Override
	public List<Map<String, Object>> selectexportPcDetailByConditionForPage(List<String> showColumns,
			String[] additionalColumns, String condition, Page page, String pcId) {
		List<String> conditions = SQLBuilder.createConditionSql(condition);
		List<Map<String, Object>> batchLogs = scoreRunningDao.selectexportPcDetailByConditionForPage(showColumns, additionalColumns,
				conditions, page, pcId);

		return batchLogs;
	}

	
	
	@Override
	public List<Map<String, Object>> selectexportPcDetailByCondition(List<String> showColumns,
			String[] additionalColumns, String condition, String pcId) {
		List<String> conditions = SQLBuilder.createConditionSql(condition);
		List<Map<String, Object>> batchLogs = scoreRunningDao.selectexportPcDetailByCondition(showColumns, additionalColumns,
				conditions,  pcId);

		return batchLogs;
	}

}
